<?php

namespace App\Helpers;

use \App\Helpers\LoggerHelper;

/**
 * CURL 类库
 * @package Mobile\Libraries
 */
class CURL {

    private $jsonEncodeOption;

    function __construct($jsonEncodeOption = true) {
        $this->jsonEncodeOption = $jsonEncodeOption;
    }

    /**
     * 发起请求
     * @param string $url 资源地址
     * @param array $body 请求数据
     * @param array $headers 请求头
     * @param string $type 请求方式
     * @param string $authInfo 认证信息
     * @return mixed
     */
    function request($url, $body = array(), $headers = array(), $type = "POST", $authInfo = "") {
        //1.创建一个curl资源
        $ch = curl_init();
        //2.设置URL和相应的选项
        curl_setopt($ch, CURLOPT_URL, $url);//设置url
        //设置为false,只会获得响应的正文(true的话会连响应头一并获取到)
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_TIMEOUT, 0); // 设置超时限制防止死循环
        //设置发起连接前的等待时间，如果设置为0，则无限等待。
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0);
        //将curl_exec()获取的信息以文件流的形式返回，而不是直接输出。
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        //2)设备请求体
        if ($body && count($body) > 0) {
            if (in_array('Content-Type:application/json', $headers)) {
                $body = json_encode($body, $this->jsonEncodeOption);
            }
            curl_setopt($ch, CURLOPT_POSTFIELDS, $body);//全部数据使用HTTP协议中的"POST"操作来发送。
        }
        //3)设置请求头
        if ($headers && count($headers) > 0) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        }
        if ($authInfo) {
            curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
            curl_setopt($ch, CURLOPT_USERPWD, $authInfo);
        }

        //上传文件相关设置
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_MAXREDIRS, 3);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);// 对认证证书来源的检查
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);// 从证书中检查SSL加密算

        //3)设置提交方式
        switch ($type) {
            case "GET":
                curl_setopt($ch, CURLOPT_HTTPGET, true);
                break;
            case "POST":
                curl_setopt($ch, CURLOPT_POST, true);
                break;
            case "PUT"://使用一个自定义的请求信息来代替"GET"或"HEAD"作为HTTP请求。这对于执行"DELETE" 或者其他更隐蔽的HTT
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
                break;
            case "DELETE":
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
                break;
        }


        //4)在HTTP请求中包含一个"User-Agent: "头的字符串。-----必设

        curl_setopt($ch, CURLOPT_USERAGENT, 'SSTS Browser/1.0');
        curl_setopt($ch, CURLOPT_ENCODING, 'gzip');

        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)'); // 模拟用户使用的浏览器
        //5)
        //3.抓取URL并把它传递给浏览器
        $res = curl_exec($ch);

        if (BUILD_VERSION !== BUILD_RELEASE) {

            //$url, $body = array(), $header = array(), $type = "POST", $authInfo = ""
            LoggerHelper::info("请求URL:{$url}");
            LoggerHelper::info("请求参数:" . json_encode($body));
            LoggerHelper::info("请求头：" . json_encode($headers));
            LoggerHelper::info("请求方式：{$type}");
            if ($authInfo)
                LoggerHelper::info("请求认证信息：" . json_encode($authInfo));
            LoggerHelper::info("请求结果:{$res}");
        }

        $result = json_decode($res, true);
        //4.关闭curl资源，并且释放系统资源
        curl_close($ch);
        if (empty($result) || !$result)
            return $res;
        else
            return $result;
    }


    /**
     * 上传文件
     * @param string $url 资源地址
     * @param $file 上传的文件对象
     * @param array $header 请求头
     * @param string $authInfo 认证信息
     * @return mixed
     */
    function uploadFile($url, $file, $header = array(), $authInfo = "") {
        //1.创建一个curl资源
        $ch = curl_init();
        //2.设置URL和相应的选项
        curl_setopt($ch, CURLOPT_URL, $url);//设置url
        //设置为false,只会获得响应的正文(true的话会连响应头一并获取到)
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_TIMEOUT, 5); // 设置超时限制防止死循环
        //设置发起连接前的等待时间，如果设置为0，则无限等待。
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
        //将curl_exec()获取的信息以文件流的形式返回，而不是直接输出。
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        //2)设备请求体
        curl_setopt($ch, CURLOPT_POSTFIELDS, $file);
        //3)设置请求头
        if ($header && count($header) > 0) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        }
        //上传文件相关设置
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_MAXREDIRS, 3);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);// 对认证证书来源的检查
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);// 从证书中检查SSL加密算

        //3)设置提交方式
        curl_setopt($ch, CURLOPT_POST, true);

        //4)在HTTP请求中包含一个"User-Agent: "头的字符串。-----必设
        curl_setopt($ch, CURLOPT_USERAGENT, 'SSTS Browser/1.0');
        curl_setopt($ch, CURLOPT_ENCODING, 'gzip');
        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)'); // 模拟用户使用的浏览器
        //3.抓取URL并把它传递给浏览器
        $res = curl_exec($ch);
        $result = json_decode($res, true);
        //4.关闭curl资源，并且释放系统资源
        curl_close($ch);
        if (empty($result))
            return $res;
        else
            return $result;
    }
}